﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using System.Globalization;
using Microsoft.VisualStudio.TestTools.UnitTesting;

using ProjectBase.Core;
using ProjectBase.Mvc.Views;
using ProjectBase.Mvc.Models;
using ProjectBase.Mvc.Controllers;

using System.Collections.Specialized;
using System.Web.Mvc;
using $prjsn$.Business;

namespace $safeprojectname$.Core.Mvc
{
    [TestClass]
    public class SmartBinder_SimpleTest : EntityTestBase<Facade>
    {
        const string TestCode = "TestCode";
        const string TestName = "TestCode";
        const int TestAge = 100;
        const int TestLimit = 200100;
        static readonly DateTime TestValidFrom = new DateTime(2000, 2, 2);
        static readonly DateTime TestValidTo = new DateTime(9998, 11, 28);

        const int TestTranslatorId = 1;
        const int TestUserId = 1;

        [TestMethod]
        public void BindValueTypes()
        {
            var binder = ProjectBase.Core.Service.Factory.CreateInstance<IObjectBinder>();
            var formatProvider = CultureInfo.GetCultureInfo("en-us");

            var nameValueCollection = FillValueProviderWithSimpleTypes(formatProvider);
            var valueProvider = new NameValueCollectionValueProvider(nameValueCollection, formatProvider);

            var entity = new DummyBindingEntity();

            binder.Bind(entity, valueProvider.ToContainer());

            AssertSimpleTypes(entity, formatProvider);
        }

        [TestMethod]
        public void BindPersistentObject()
        {
            var binder = ProjectBase.Core.Service.Factory.CreateInstance<IObjectBinder>();
            var formatProvider = CultureInfo.GetCultureInfo("en-us");

            var nameValueCollection = FillValueProviderWithPersistentObject(formatProvider);
            var valueProvider = new NameValueCollectionValueProvider(nameValueCollection, formatProvider);

            var entity = new DummyBindingEntity();

            binder.Bind(entity, valueProvider.ToContainer());

            AssertPersistentTypes(entity, formatProvider);
        }

        [TestMethod]
        public void BindValueTypes_csCZ()
        {
            var binder = ProjectBase.Core.Service.Factory.CreateInstance<IObjectBinder>();
            var formatProvider = CultureInfo.GetCultureInfo("cs-CZ");

            var nameValueCollection = FillValueProviderWithSimpleTypes(formatProvider);
            var valueProvider = new NameValueCollectionValueProvider(nameValueCollection, formatProvider);

            var entity = new DummyBindingEntity();

            binder.Bind(entity, valueProvider.ToContainer());

            AssertSimpleTypes(entity, formatProvider);
        }

        [TestMethod]
        public void BindPersistentObject_csCZ()
        {
            var binder = ProjectBase.Core.Service.Factory.CreateInstance<IObjectBinder>();
            var formatProvider = CultureInfo.GetCultureInfo("cs-CZ");

            var nameValueCollection = FillValueProviderWithPersistentObject(formatProvider);
            var valueProvider = new NameValueCollectionValueProvider(nameValueCollection, formatProvider);

            var entity = new DummyBindingEntity();

            binder.Bind(entity, valueProvider.ToContainer());

            AssertPersistentTypes(entity, formatProvider);
        }
        [TestMethod]
        public void BindValueTypes_deAT()
        {
            var binder = ProjectBase.Core.Service.Factory.CreateInstance<IObjectBinder>();
            var formatProvider = CultureInfo.GetCultureInfo("de-AT");

            var nameValueCollection = FillValueProviderWithSimpleTypes(formatProvider);
            var valueProvider = new NameValueCollectionValueProvider(nameValueCollection, formatProvider);

            var entity = new DummyBindingEntity();

            binder.Bind(entity, valueProvider.ToContainer());

            AssertSimpleTypes(entity, formatProvider);
        }

        [TestMethod]
        public void BindPersistentObject_deAT()
        {
            var binder = ProjectBase.Core.Service.Factory.CreateInstance<IObjectBinder>();
            var formatProvider = CultureInfo.GetCultureInfo("de-AT");

            var nameValueCollection = FillValueProviderWithPersistentObject(formatProvider);
            var valueProvider = new NameValueCollectionValueProvider(nameValueCollection, formatProvider);

            var entity = new DummyBindingEntity();

            binder.Bind(entity, valueProvider.ToContainer());

            AssertPersistentTypes(entity, formatProvider);
        }

        #region protected
        static NameValueCollection FillValueProviderWithSimpleTypes(CultureInfo formatProvider)
        {
            var nameValueCollection = new NameValueCollection();

            nameValueCollection["Code"] = TestCode;
            nameValueCollection["Name"] = TestName;
            nameValueCollection["Age"] = TestAge.ToString(formatProvider);
            nameValueCollection["Limit"] = TestLimit.ToString(formatProvider);
            nameValueCollection["ValidFrom"] = TestValidFrom.ToString(formatProvider);
            nameValueCollection["ValidTo"] = TestValidTo.ToString(formatProvider);

            return nameValueCollection;
        }


        static NameValueCollection FillValueProviderWithPersistentObject(CultureInfo formatProvider)
        {
            var nameValueCollection = FillValueProviderWithSimpleTypes(formatProvider);
            nameValueCollection["FirstTranslator"] = TestTranslatorId.ToString(formatProvider);
            nameValueCollection["User"] = TestUserId.ToString(formatProvider);
            return nameValueCollection;
        }

        static void AssertSimpleTypes(DummyBindingEntity entity, CultureInfo formatProvider)
        {
            Assert.AreEqual(entity.Code, TestCode, "Code does not match expected value '{0}'", TestCode.ToString(formatProvider));
            Assert.AreEqual(entity.Name, TestName, "Name does not match expected value '{0}'", TestName.ToString(formatProvider));
            Assert.AreEqual(entity.Age, TestAge, "Age does not match expected value '{0}'", TestAge.ToString(formatProvider));
            Assert.AreEqual(entity.Limit, TestLimit, "Limit does not match expected value '{0}'", TestLimit.ToString(formatProvider));
            Assert.AreEqual(entity.ValidFrom, TestValidFrom, "ValidFrom does not match expected value '{0}'", TestValidFrom.ToString(formatProvider));
            Assert.AreEqual(entity.ValidTo, TestValidTo, "ValidTo does not match expected value '{0}'", TestValidTo.ToString(formatProvider));
        }
        static void AssertPersistentTypes(DummyBindingEntity entity, CultureInfo formatProvider)
        {
            Assert.IsNotNull(entity.User, "User property should be bounded");
            Assert.IsNotNull(entity.FirstTranslator, "FirstTranslator property should be bounded");

            Assert.AreEqual(entity.FirstTranslator.ID, TestTranslatorId, "FirstTranslator ID does not match expected value '{0}'", TestTranslatorId.ToString(formatProvider));
            Assert.AreEqual(entity.User.ID, TestUserId, "User ID does not match expected value '{0}'", TestUserId.ToString(formatProvider));
        }
        #endregion protected

        #region Additional test attributes
        //
        // You can use the following additional attributes as you write your tests:
        //
        // Use ClassInitialize to run code before running the first test in the class
        // [ClassInitialize()]
        // public static void MyClassInitialize(TestContext testContext) { }
        //
        // Use ClassCleanup to run code after all tests in a class have run
        // [ClassCleanup()]
        // public static void MyClassCleanup() { }
        //
        [TestInitialize]
        public override void MyTestInitialize()
        {
            base.MyTestInitialize(); // Use TestInitialize to run code before running each test
        }

        [TestCleanup]
        public override void MyTestCleanup()
        {
            base.MyTestCleanup(); // Use TestCleanup to run code after each test has run
        }
        #endregion
    }
}
